#include <stdlib.h>
#include <zephyr.h>

#include <shell/shell.h>
#if !defined(CONFIG_SHELL)
#undef shell_print
#undef shell_hexdump
#define shell_print(_sh, _ft, ...)
#define shell_hexdump(...)
#endif

#include <logging/log_ctrl.h>
#include <logging/log.h>
LOG_MODULE_REGISTER(logging_sample, CONFIG_LOGGING_SAMPLE_LOG_LEVEL);

static int logging_normal_test(const struct shell *shell, size_t argc, char **argv)
{
	int a = 3;
	int b = -5;

	double c = 3.5;
	double d = 4.34e-5;
	double e = 2.113e10;

	char f = 4;
	short g = 5;
	long h = 100;
	double i= 5e8;
	long long j = 6e8;

	size_t l = 34;
	char *p1 = &f;
	char *p2= (char*)&g;
	ptrdiff_t m = p2 - p1;

	printk("+: %+d, %d\r\n",a,a);
	printk("+: %+d, %d\r\n",b,b);

	printk("space: % d, %d\r\n",a,a);
	printk("space: % d, %d\r\n",b,b);

	printk("-: %-d, %d\r\n",a,a);
	printk("-: %-d, %d\r\n",b,b);

	printk("0: %04d, %d\r\n",a,a);
	printk("0: %04d, %d\r\n",b,b);

	printk("#: %#x, %x\r\n", a, a);
	printk("#: %#f, %f\r\n", c, c);
	printk("#: %#e, %e\r\n", d, d);
	printk("#: %#g, %g\r\n", e, e);

	printk("*: %0*d, %d\r\n", 8, a, a);

	printk(".: %.*s\r\n", 3, "abcdef");
	printk(".: %.4s\r\n", "abcdef");

	printk("hh: %hhd\r\n", f);
	printk("h: %hd\r\n", g);
	printk("l: %ld, %ld\r\n", h, (long)i);
	printk("ll: %lld\r\n", j);
	printk("L: %Ld\r\n", (long long )a);
	printk("z: %zd\r\n", l);
	printk("j: %jd\r\n", j);
	printk("t: %td\r\n", m);

	int n = 0;
	printk("test: %n\r\n", &n);
	printk("read n = %d\r\n", n);
	printk("%%a: %a\r\n", c);

	return 0;
}

extern void simple_logging(void);
extern void simple_co_logging(void);
extern void simple_header_logging(void);
static int logging_simple_test(const struct shell *shell, size_t argc, char **argv)
{
	simple_logging();
	simple_co_logging();
	simple_header_logging();
	return 0;
}

extern void instance_logging(void);
static int logging_instance_test(const struct shell *shell, size_t argc, char **argv)
{
	instance_logging();
	return 0;
}

#if !defined(CONFIG_LOG_MODE_MINIMAL)
/* 获取source id的函数需要自己实现 */
static int16_t log_source_id_get(const char *name)
{
	/* 使用log_source_name_get取出每个source的名称做对比，确认source的id */
	for (int16_t i = 0; i < log_src_cnt_get(CONFIG_LOG_DOMAIN_ID); i++) {
		if (strcmp(log_source_name_get(CONFIG_LOG_DOMAIN_ID, i), name)
		    == 0) {
			return i;
		}
	}

	return -1;
}
#endif /* CONFIG_LOG_MODE_MINIMAL */

static int logging_filter_test(const struct shell *shell, size_t argc, char **argv)
{
#if !defined(CONFIG_LOG_MODE_MINIMAL)
	uint32_t level = strtol(argv[1], NULL, 0);
	uint32_t act_level = 0;

	shell_print(shell, "Set filter level %d", level);
	act_level = log_filter_set(NULL, 	/* 第一个参数为backend，如果为NULL表示对所有的backend都进行设置 */
					0,					/* 第二个参数为domain_id，目前不支持多dimain，直接给0 */
			    	log_source_id_get(STRINGIFY(logging_sample)), /* 第三个参数为source_id，代表的是要设置那个模块的等级，这里我们要设置logging_sample */
			    	level);				/* 第四个参数为level，表示要设置的过滤等级 */

	/* 返回的act_level为实际生效的level */
	shell_print(shell, "Set filter level %d act is %d", level, act_level);
#endif /* CONFIG_LOG_MODE_MINIMAL */

	LOG_ERR("Error message example.");
	LOG_WRN("Warning message example.");
	LOG_INF("Info message example.");
	LOG_DBG("Debug message example.");

	return 0;
}

SHELL_STATIC_SUBCMD_SET_CREATE(sub_logging,
			       SHELL_CMD(run, NULL, "run normal test", logging_normal_test),
				   SHELL_CMD_ARG(filter, NULL, "run filter test", logging_filter_test, 2, 0),
				   SHELL_CMD(simple, NULL, "run simple test", logging_simple_test),
				   SHELL_CMD(instance, NULL, "run instance test", logging_instance_test),
			       SHELL_SUBCMD_SET_END
			       );

SHELL_CMD_REGISTER(logging, &sub_logging, "logging test commands", NULL);